/*******************************************************************
This file is part of iAgenda.

iAgenda is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

iAgenda is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with iAgenda.  If not, see <http://www.gnu.org/licenses/>.
*******************************************************************/
//#define EDB1
#include "stdafx.h"
#include <initguid.h>
#include "GraphicFunctions.h"
#include "ListDataPoom.h"
#include "FileUtils.h" 
#include "iAgenda.h"  //ajige 5/11 in order to go back to previous screen when clicking complete on a task.
#include <windbase.h>
#include <windows.h>
#include <algorithm> //2/22 ajige for array sort
#include <vector> //4/5/10
//#include <windbase_edb.h>
///////ajige 6/2 start of edb code for testing
extern "C"  
{
 #include <windbase_edb.h>
}

#define DB_VOL_FN		 TEXT("pim.vol")
#define APPTMT_DB_NAME  TEXT("Appointments Database")
#define TAKS_DB_NAME TEXT("Tasks Database")
#define CONTACTS_DB_NAME TEXT("Contacts Database")//ajige 6/5: in order to read birthdays and anniversaries
typedef int (*compfn)(const void*, const void*);

//This is not neccessary as they are all defined by Microsoft:
//http://msdn.microsoft.com/en-us/library/aa454518.aspx
//#define MAKEPROP(n,t)    ((n<<16)|CEVT_##t)
//#define PROPID_LOCATION	MAKEPROP(0x0041, LPWSTR)
//#define PROPID_SUBJECT  MAKEPROP(0x0020, LPWSTR)

std::vector <DataItem *> vApptmnt;  //4/26/10
extern SYSTEMTIME stToday;	// system local time
DATE dtToday;				// poom local time
DATE iToday;				// poom local time "serial"

IPOutlookApp2 *             polApp;
IFolder *                   pCurrFldr;
IPOutlookItemCollection *   pItemCol;
//
//
const TCHAR *               tszCategory;
UINT                        nBitmapHeight;
UINT                        nBitmapWidth;

//DataItem    *diArray = NULL;
//	int     count = 0; // Keeps track of the number of elements used
//	int     num_allocated = 0; // This is essentially how large the array is

// Internal functions to be used by the functions in this file
HRESULT initPoom();//not necessary ScreenDefinition  hgScreen);

// http://msdn.microsoft.com/en-us/library/bb446087.aspx
HRESULT PoomCategoriesPopulate(ScreenDefinition  hgScreen,DataItem * parent, void (*adder)(DataItem*),
                     CSettings * pSettings) {
//ajige this is not used

    HRESULT           hr = E_FAIL;
    IFolder    * pFolder = NULL;
    IItem * pFolderIItem = NULL;
    CEPROPVAL    * pVals = NULL;
    ULONG       cbBuffer = 0;
    int            index = 0;
    DataItem        data = {0};

    //ajige Changed to 0 below data.ID = 1;
    data.iGroup = 0;
    //data.isFavorite = false; //ajige changed to isTask;
    data.isTask = false;
	data.isOverdue = false;
    data.oId = 0;
    data.type = diListItem;
    data.ID = 0;
		//if(hgScreen.hgScreen==0) //ajige 
	if(parent->szPrimaryText==pSettings->allappointments_string)
		StringCchCopy(data.szPrimaryText, 64, pSettings->allappointments_string);
		//else if (hgScreen.hgScreen==1)//ajige
	else if(parent->szPrimaryText ==pSettings->alltasks_string)
		StringCchCopy(data.szPrimaryText, 64, pSettings->alltasks_string); 
	else if (parent->szPrimaryText ==pSettings->agenda_string)
		//else if(hgScreen.hgScreen==2) //ajige
		StringCchCopy(data.szPrimaryText, 64, pSettings->agenda_string);
	adder(&data);

    data.ID = 1;

    CEPROPID rgPropID = PIMPR_FOLDER_CATEGORIES;

    initPoom();//hgScreen);  //ajige added hgScreen, not neccessary
    HANDLE hHeap = GetProcessHeap();

    // Get the IFolder object (Contacts, Calendar, Tasks).
	//ajige might need adjustments for Agenda when filtering categories
		//if(hgScreen.hgScreen==0)
	if(parent->szPrimaryText==pSettings->allappointments_string)
		hr = polApp->GetDefaultFolder(olFolderCalendar, &pFolder);
			//else if(hgScreen.hgScreen==1)
	else if(parent->szPrimaryText==pSettings->alltasks_string)
		 hr = polApp->GetDefaultFolder(olFolderTasks, &pFolder); 
    
	CHR(hr);

    // Get the IItem object representing a IFolder object.
    hr = pFolder->QueryInterface(__uuidof(IItem), (LPVOID*)&pFolderIItem);
    CHR(hr);

    // Get the list of categories.
    hr = pFolderIItem->GetProps(&rgPropID, CEDB_ALLOWREALLOC, 1, &pVals, &cbBuffer, hHeap);
    CHR(hr);

    // Copy the list of categories for use outside of this function.
    TCHAR * start = pVals->val.lpwstr;
    TCHAR * end = start + _tcslen(pVals->val.lpwstr);
    TCHAR * comma;
    while (start < end) {
        comma = _tcschr(start, ',');
        if (comma == NULL) comma = end;
        hr = StringCchCopyN(data.szPrimaryText, 64, start, comma - start);
       //ajige data.isFavorite = 0 == _tcscmp(data.szPrimaryText, pSettings->favorite_category);
        CHR(hr);
        adder(&data);
        start = comma + 2;
    }

Error:
    // Free resources.
    HeapFree(hHeap, 0, pVals);
    RELEASE_OBJ(pFolderIItem);
    RELEASE_OBJ(pFolder);

    return index;
}

HRESULT PoomCategoriesGetTitle(ScreenDefinition  hgScreen,DataItem * parent, TCHAR * buffer, int cchDest,
                               CSettings * pSettings) {
	//ajige hgscreen not necessary
    StringCchCopy(buffer, cchDest, pSettings->categories_string);
	
    return S_OK;
}

HRESULT PoomCategoriesClick(ScreenDefinition  hgScreen,DataItem * data, float x, 
                            int * newScreen, CSettings * pSettings) {
	//hgScreen not neccessary
	*newScreen = 4;
    return S_OK;
}


/* qsort struct comparision function */
int struct_cmp_by_date(struct DataItem *elem1, struct DataItem *elem2)
{
	if ( elem1->iGroup < elem2->iGroup)
		return -1;
	
	else if (elem1->iGroup > elem2->iGroup)
	   return 1;
	
	else
	   return 0;
 
} 
bool compareVect(struct DataItem *x, DataItem *y)
{
	return x->iGroup < y->iGroup;
}
//http://fydo.net/gamedev/dynamic-arrays
/*int AddToArray (DataItem  item)
{
	
        if(count == num_allocated) // Are more refs required?
        {
                // Feel free to change the initial number of refs
                // and the rate at which refs are allocated.
                if (num_allocated == 0)
                        num_allocated = 50; // Start off with 3 refs
                else
                        num_allocated = count*2; // Double the number
                                                    // of refs allocated

                // Make the reallocation transactional
                // by using a temporary variable first
                void *_tmp = realloc(diArray, (num_allocated * sizeof(DataItem)));

                // If the reallocation didn't go so well,
                // inform the user and bail out
                if (!_tmp)
                {
                        MessageBox(0, L"ERROR: Couldn't realloc memory!\n",SZ_APP_NAME, 0);
                        return(-1);
                }

                // Things are looking good so far
                diArray = (DataItem*)_tmp;
        }

        diArray[count] = item;
        count++;

        return count;
}

*/
// *************************************************
// These functions are for the main list of appointments/tasks
// *************************************************

HRESULT PoomPopulate(ScreenDefinition hgScreen, DataItem * parent, void (*adder)(DataItem*),
					 CSettings * pSettings )
{  	
	

	HRESULT hr = S_OK;
	BSTR bstrPrimary = NULL;
	IItem     *pItem   = NULL;		//ajige moved
	CEPROPVAL propval  = {0};		//ajige moved

	//poom date
	DATE dtStart;
	DATE dtDue;

	//filter for time span
	//TODO: is max_path too long?
		//TCHAR szFrom[MAX_PATH];
		//TCHAR szTo[MAX_PATH];
		//TCHAR szDateFilter[MAX_PATH];
		//int nTimeSpan;

	// This will hold our "next" list item, which we'll later
	// pass to this->_addListItem
	DataItem data = {0};
	data.iGroup = 0;
	data.isTask = false;
	data.isOverdue = false;
	data.isUndated = false; //ajige from tasks
	data.isComplete = false;  //1/20/10
	data.type = diListItem;

	hr = initPoom();
	CHR(hr);

	// get the date "serial"
	SystemTimeToVariantTime(&stToday, &dtToday);
	iToday = (UINT)dtToday;


//==============================================
#if defined EDB1
	{
		//Problems with this code:
		// tasks are not sorted: If I add sort to the opendb function, it says "The parameter is incorrect". 
		//However, same code works for appointments.
		//Recurring appointments onlys show on first day, same with tasks?
		//birthdays and annivarsaries has to be fetched from another database. How will that affect sorting?
	//MessageBox(0,L"EDB",L"",MB_OK);
////ajige 6/2 start of edb code for testing
	CEGUID guid = {0}; //ajige 6/2
	//CEGUID guid2 = {0}; 
	HANDLE hdb = 0;
	CEOID oid = 0;
	SORTORDERSPECEX sort = {0};
	
	BOOL    ret = false; 
	
	//Appointments
	//ajige 6/5: TODO : Fix recurring, add anniversaries, birthdays
	//otherwise working on all screens?
	if(hgScreen.hgScreen == 0 || hgScreen.hgScreen == 2) 
	{

		sort.wVersion = SORTORDERSPECEX_VERSION;
	sort.wNumProps = 1;
	sort.wKeyFlags = 0;
	sort.rgPropID[0] = PIMPR_START;//PROPID_START_TIME;
	sort.rgdwFlags[0] = CEDB_SORT_DESCENDING;
	if (!guid.Data1) //ajige 6/2
	{
		ret=CeMountDBVolEx(&guid, DB_VOL_FN, NULL, OPEN_EXISTING);
	}
   // if (ret) //6/13
	{
		HANDLE 	hSession = CeCreateSession(&guid);
		if (hSession != INVALID_HANDLE_VALUE) 
		{
			//MessageBox(0,L"",L"if ret",MB_OK);
			//CEOID ceoid = 0;
			//hdb = CeOpenDatabaseInSession(NULL, &guid, &oid, APPTMT_DB_NAME,&sort, CEDB_AUTOINCREMENT, NULL);
			hdb = CeOpenDatabaseInSession(hSession, &guid, &oid, _T("Appointments Database"),&sort, CEDB_AUTOINCREMENT, NULL);
			//hdb = CeOpenDatabaseInSession(NULL, &guid, &oid, _T("Appointments Database"),&sort, CEDB_AUTOINCREMENT, NULL);
		}
	}
	
	//if (hdb == INVALID_HANDLE_VALUE) //6/12 otherwise when changing dates=> error
	{
   //     MessageBox(0,L"",L"Error opening Appointments Database",MB_OK);
    }
	//else
	{
		WORD   wNumProps;
		DWORD  dwBufSize = 0;
		CEPROPVAL * pRecord = NULL;
		WORD i;
		FILETIME ftToday;
		SystemTimeToFileTime(&stToday,&ftToday);
		CEPROPVAL propVals[1];
        propVals[0].propid = PIMPR_START;
        propVals[0].wFlags = 0;
        propVals[0].wLenData = 0;
		propVals[0].val.filetime = ftToday;
		DWORD dwIndex = 0;
		TCHAR * pszName;
		FILETIME ftStart;
		SYSTEMTIME stStart;
		oid = CeSeekDatabaseEx (hdb, CEDB_SEEK_BEGINNING, 0, 1, & dwIndex);//works
		/*if (hgScreen.hgScreen == 2) //agenda, only show today, doesn;t work
		{
			propVals[1].propid = PIMPR_START;
			propVals[1].wFlags = 0;
			propVals[1].wLenData = 0;
			SYSTEMTIME stTomorrow=stToday;
			stTomorrow.wDay++;
			//stToday.wDay++;//tomorrow
			SystemTimeToFileTime(&stTomorrow,&ftToday);
			propVals[1].val.filetime = ftToday;
			oid=CeSeekDatabaseEx (hdb, CEDB_SEEK_VALUEFIRSTEQUAL, (DWORD) & propVals, 2, & dwIndex);
			//stToday.wDay--;
		}
		else*/
			//2/17/10 oid=CeSeekDatabaseEx (hdb, CEDB_SEEK_VALUEGREATER, (DWORD) & propVals, 1, & dwIndex);
			oid=CeSeekDatabaseEx (hdb, CEDB_SEEK_VALUESMALLER, (DWORD) & propVals, 1, & dwIndex);
		for (i = 0; i < 300; i++) 
		{
			oid = CeReadRecordPropsEx(hdb, CEDB_ALLOWREALLOC, &wNumProps, NULL,
				(LPBYTE *)&pRecord, &dwBufSize, NULL);
			if (!oid)
				break;
			pszName = NULL;
			VARIANT_BOOL bIsAllDay = false;
			for (WORD iProp = 0; iProp < wNumProps; iProp++) 
			{
				switch(pRecord[iProp].propid) 
				{
					case PIMPR_SUBJECT:
						pszName = pRecord[iProp].val.lpwstr;
						//MessageBox(0,pRecord[iProp].val.lpwstr,L"Subject",MB_OK);
						break;
					case PIMPR_ALL_DAY_EVENT:
						bIsAllDay=pRecord[iProp].val.boolVal;
						break;
					case PIMPR_START:
						FILETIME ftLocal;
						
						
						ftStart = pRecord[iProp].val.filetime;
						FileTimeToLocalFileTime(&ftStart,&ftLocal);
						FileTimeToSystemTime(&ftLocal,&stStart);
						SystemTimeToVariantTime(&stStart,&dtStart);
						
						
						// we'll store the oid as the low order word of the call time,
						// this, along with the approximate index, i, should lead us
						// directly to the call (even if another call has been placed since)
						//data.oId = ftStart.dwLowDateTime;

						//data.iGroup = _getPastTime(ftStart, data.szSecondaryText, 
						//	SECONDARY_TEXT_LENGTH);
						break;
						//MessageBox(0,pRecord[iProp].val.lpwstr,L"Subject",MB_OK);
						//break;
				}
			}
			data.ID = i;
        StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH,  pszName);
		if(bIsAllDay)
		{
			StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, pSettings->allday_string);
		}
		else
		{
			_printHour(data.szTertiaryText, MAX_PATH, dtStart);
		}
		UINT dtStartGroup = (UINT)dtStart;
		//ajige 4/16 only do the group code for all appointments screen.
		if(hgScreen.hgScreen == 0) //ajige: not grouping on agenda screen
		{
			if (NULL == tszCategory) {
				data.iGroup = (UINT)dtStartGroup;
			}
		}
		// allelimo: group header for agenda tab
		else
		{
			if (NULL == tszCategory) {
				data.iGroup = 10;
			}
		}
		if (oid)
			if (hgScreen.hgScreen == 2) //agenda, only show today
			{
				if( stStart.wDay==stToday.wDay
					&& stStart.wMonth==stToday.wMonth
					&& stStart.wYear==stToday.wYear)
						adder(&data);
			}
			else
				adder(&data);
		//if (hgScreen.hgScreen == 2) //agenda, only show today ,except probably test for one time like 12 am
		//	oid=CeSeekDatabaseEx (hdb, CEDB_SEEK_VALUENEXTEQUAL, (DWORD) & propVals, 2, & dwIndex); 

		}
		 

		/*for (i = 0; i < 100; i++) {  //works
			oid = CeReadRecordPropsEx(hdb, CEDB_ALLOWREALLOC, &wNumProps, NULL,
			(LPBYTE *)&pRecord, &dwBufSize, NULL);
			for (WORD iProp = 0; iProp < wNumProps; iProp++) 
			{
				switch(pRecord[iProp].propid) 
				{
					//case 0x0041001F: //location
					case PIMPR_LOCATION:
						MessageBox(0,pRecord[iProp].val.lpwstr,L"Location",MB_OK);
						break;

					//case 0x0020001F: //subject
					case PIMPR_SUBJECT:
						MessageBox(0,pRecord[iProp].val.lpwstr,L"Subject",MB_OK);
						break;
				}
			}
		}*/
	}
	if (hdb != 0 && hdb == INVALID_HANDLE_VALUE)
	    CloseHandle(hdb);
	
	//CeUnmountDBVol(&guid);
  //      guid.Data1 = NULL;
}

//tasks  sjige 6/5

if(hgScreen.hgScreen == 1 || hgScreen.hgScreen == 2) 
	{
		sort.wVersion = SORTORDERSPECEX_VERSION;
		sort.wNumProps = 1;
		sort.wKeyFlags = 0;
		sort.rgPropID[0] = PIMPR_DUE_DATE;
		sort.rgdwFlags[0] = CEDB_SORT_DESCENDING;
	HANDLE hdb2=0;
	if (!guid.Data1) 
	{
		//ret=CeMountDBVolEx(&guid2, DB_VOL_FN, NULL, OPEN_EXISTING);
	//	ret=CeMountDBVolEx(&guid2, L"pim.vol", NULL, OPEN_EXISTING);
		ret= CeMountDBVolEx(&guid, DB_VOL_FN, NULL, OPEN_EXISTING);

    hdb2 = CeOpenDatabaseInSession(NULL, &guid, &oid, _T("Tasks Database"),NULL, CEDB_AUTOINCREMENT, NULL);
   //hdb2 = CeOpenDatabaseInSession(NULL, &guid, &oid, _T("Tasks Database"),
	//   &sort, CEDB_AUTOINCREMENT, NULL);

	}
   // if (ret) 
	{
		//HANDLE hSession = CeCreateSession(&guid);
		//if (hSession != INVALID_HANDLE_VALUE) 
		//{
			//CEOID ceoid = 0;
		//	hdb2 = CeOpenDatabaseInSession(hSession, &guid, &oid, _T("Tasks Database"),&sort, CEDB_AUTOINCREMENT, NULL);
		
		//}
	}
	
	if (hdb2 == INVALID_HANDLE_VALUE) 
	{
		LPVOID lpMsgBuf;
		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
						FORMAT_MESSAGE_FROM_SYSTEM | 
						FORMAT_MESSAGE_IGNORE_INSERTS,
						NULL,GetLastError(),0, (LPTSTR) &lpMsgBuf,
						0,	NULL 	);		
		MessageBox( NULL, (LPCTSTR)lpMsgBuf, L"Error opening tasks database", MB_OK | MB_ICONINFORMATION );
		// Free the buffer.
		LocalFree( lpMsgBuf );		
    }
	else
	{
		WORD   wNumProps;
		DWORD  dwBufSize = 0;
		CEPROPVAL * pRecord = NULL;
		WORD i;
		FILETIME ftToday;
		SystemTimeToFileTime(&stToday,&ftToday);
		CEPROPVAL propVals[1];
        propVals[0].propid = PIMPR_DUE_DATE;
        propVals[0].wFlags = 0;
        propVals[0].wLenData = 0;
		propVals[0].val.filetime = ftToday;
		DWORD dwIndex = 0;
		TCHAR * pszName;
		FILETIME ftDue;
		SYSTEMTIME stDue;
		oid = CeSeekDatabaseEx (hdb2, CEDB_SEEK_BEGINNING, 0, 1, & dwIndex);//works
		oid=CeSeekDatabaseEx (hdb2, CEDB_SEEK_VALUESMALLER, (DWORD) & propVals, 1, & dwIndex);
		for (i = 0; i < 300; i++) 
		{
			oid = CeReadRecordPropsEx(hdb2, CEDB_ALLOWREALLOC, &wNumProps, NULL,
				(LPBYTE *)&pRecord, &dwBufSize, NULL);
			if (!oid)
				break;
			pszName = NULL;
			VARIANT_BOOL bIsComplete= false;
			
			for (WORD iProp = 0; iProp < wNumProps; iProp++) 
			{
				//if(pRecord[iProp].propid==PIMPR_COMPLETE &&
				//	pRecord[iProp].val.boolVal==false)=> goes into a loop
				{
				switch(pRecord[iProp].propid) 
				{
					case PIMPR_SUBJECT:
						pszName = pRecord[iProp].val.lpwstr;
						break;

					case PIMPR_COMPLETE:
						bIsComplete = pRecord[iProp].val.boolVal;
						break;
					
					case PIMPR_DUE_DATE:
						FILETIME ftLocal;							
						ftDue = pRecord[iProp].val.filetime;
						FileTimeToLocalFileTime(&ftDue,&ftLocal);
						FileTimeToSystemTime(&ftLocal,&stDue);
						SystemTimeToVariantTime(&stDue,&dtDue);	
						// now check if it is an undated task
						if(stDue.wYear == 4501) // undated task?
						{
							data.isUndated = true;
						}
						else
							data.isUndated = false;
						// check if it is overdue
						if (dtDue < iToday)
							data.isOverdue = true;
						else
							data.isOverdue = false; //ajige: otherwise all but undated is considered overdue
							//sort and group by due date							
						// grouping: get serial from date
						UINT dtDueGroup = (UINT)dtDue;

						//now we know if it's overdue, grouping
						//if(hgScreen.hgScreen == 1)
						//{				 
							//Don't display groups if filtered by category
						//	if (NULL == tszCategory) //ajige 4/27 moved
						//	{
								//data.iGroup = dtDueGroup;
						//		data.iGroup = (UINT)dtDue;
							if(data.isUndated)
								data.iGroup = 1;
						//	else 
							if(data.isOverdue)
								data.iGroup = 2; // todo: check if this must remain hardcoded		
						//	}
						//}
						// allelimo: group header for agenda tab
						//else
						//{				 
							//Don't display groups if filtered by category
						//	if (NULL == tszCategory) 
						//		data.iGroup = 11;
						//}
						// due date for overdue tasks, undated string for undated tasks
						if (data.isOverdue)
						{
							_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtDue);
						}
						else
						{
							StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, TEXT(""));
						}
						break;
				}
				}
			}
			data.ID = i;
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH,  pszName);
		
				UINT dtStartGroup = (UINT)dtDue;
				//ajige 4/16 only do the group code for all appointments screen.
				if(hgScreen.hgScreen == 1) //ajige: not grouping on agenda screen
				{
					if (NULL == tszCategory) {
						data.iGroup = (UINT)dtStartGroup;
					}
				}
				// allelimo: group header for agenda tab
				else
				{
					if (NULL == tszCategory) {
						data.iGroup = 11;
					}
				}
				if (oid)
					if (!bIsComplete)
					{
					if (hgScreen.hgScreen == 2) //agenda, only show due on or before today
					{
						SYSTEMTIME stTomorrow=stToday;
						stTomorrow.wDay++;
						if( stDue.wDay<stTomorrow.wDay
							&& stDue.wMonth<stTomorrow.wMonth
							&& stDue.wYear<stTomorrow.wYear)
								adder(&data);
					}
					else
						adder(&data);
					}
				}
			}
	if (hdb2 != 0 && hdb2 == INVALID_HANDLE_VALUE)
	    CloseHandle(hdb2);
}}

#else
#if defined AJIGE_TEST  //ajige 2/12/10
{	
	//to make it like Poommaster sample which is a lot faster	
	
	int cItems = 0;
//=============APPOINTMENTS
	if(hgScreen.hgScreen == 0|| hgScreen.hgScreen == 2) //appointments
	{
			//IPOutlookItemCollection *pRestrict;
		IAppointment * pAppointment = NULL;
			//TCHAR szCount[255];
		SYSTEMTIME stNow;
		DATE dtNow;
		SYSTEMTIME st;	
		//save all appointments to a vector which allows
		//multiple recurrences and multiday		
		vApptmnt.clear();
		//std::vector <DataItem *> vApptmnt(0); made global in order to use it for the calendar popup
		// however, since this is limited as per timespan, need to change TODO
		//also if this is a global, every time this function is called, the vector is added to
		// => need to set to null before first adder
		long lRecurrenceType = 0;
		int nTimeSpan = 1;

		hr = polApp->GetDefaultFolder(olFolderCalendar, &pCurrFldr); 
		CHR(hr);
		hr=pCurrFldr->get_Items(&pItemCol);
		CHR(hr);
		hr=pItemCol->get_Count(&cItems);
		CHR(hr);
		GetLocalTime(&stNow);
		SystemTimeToVariantTime(&stNow,&dtNow);		
		
		// Set the folder's properties. 4/8/10  
		hr = pCurrFldr->QueryInterface(IID_IItem, (LPVOID*)&pItem);
		CHR(hr);
		propval.propid    = PIMPR_FOLDERNOTIFICATIONS;
		propval.val.ulVal = PIMFOLDERNOTIFICATION_ALL;
		hr                = pItem->SetProps(0, 1, &propval);
		CHR(hr);

		// time span filter 4/8/10
		if (hgScreen.hgScreen == 0) // All appointments tab, get time span from settings
		{
			if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("1 Week"), -1) == CSTR_EQUAL)
				nTimeSpan = 7;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("2 Weeks"), -1) == CSTR_EQUAL)
				nTimeSpan = 14;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("1 Month"), -1) == CSTR_EQUAL)
				nTimeSpan = 31;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("3 Months"), -1) == CSTR_EQUAL)
				nTimeSpan = 92;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("6 Months"), -1) == CSTR_EQUAL)
				nTimeSpan = 183;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("1 Year"), -1) == CSTR_EQUAL)
				nTimeSpan = 365;
		}

		for(int item=0; item < cItems; item++)//if includeRecurrences, there has to be an infinite no. otherwise, it will go to eternity
		{
			
			int nYears =0;
			TCHAR szRecurs[255];
			VARIANT_BOOL bIsRecurring = false;
			IAppointment * prApp;
			VARIANT_BOOL bIsAllDay = false;
			data.isTask = false;//ajige: used for tasks NULL != TODO change
			
			hr=pItemCol->Item(item+1,(IDispatch**)&pAppointment);
			if (FAILED(hr))
				continue;
				
			// grab properties
			hr = pAppointment->get_Oid(&data.oId);
			CHR(hr);
			hr=pAppointment->get_Subject(&bstrPrimary);
			CHR(hr);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, bstrPrimary);
			SysFreeString(bstrPrimary);
			hr = pAppointment->get_Start(&dtStart);
			CHR(hr);			
			hr = pAppointment->get_IsRecurring(&bIsRecurring);
			CHR(hr);
			hr = pAppointment->get_AllDayEvent(&bIsAllDay);
			CHR(hr);	
			
			if(bIsAllDay)	// show the time or "all day" on the right side
				StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, pSettings->allday_string);
			else
				_printHour(data.szTertiaryText, MAX_PATH, dtStart);

			if(bIsRecurring)
			{	
				IRecurrencePattern* pRec;				
				
				if (SUCCEEDED(pAppointment->GetRecurrencePattern(&pRec)))
				{	
					if(hgScreen.hgScreen == 2) //agenda
					{
						pRec->GetOccurrence(dtNow, &prApp);
						if(prApp)
						{
							data.iGroup = 10;
							//vApptmnt.push_back(&data); //doesnt work
							vApptmnt.push_back(new DataItem(data));
							//delete(&data); //4/5/10 ???
						}
					}
					else //all appointments
					{
						VARIANT_BOOL fNoEndDate = VARIANT_FALSE;
						DATE dtPatternStart;// = (DATE)nDay;
						DATE dtPatternEnd;
						long lInterval=0;
						long lInstance=0;

						pRec->get_NoEndDate(&fNoEndDate);
						pRec->get_RecurrenceType(&lRecurrenceType); //NoRecurrence = -1, Daily = 0, Weekly = 1, Monthly = 2, MonthByNumber = 3, Yearly = 5, Every Nth Year = 6
						pRec->get_PatternStartDate(&dtPatternStart);
						pRec->get_PatternEndDate(&dtPatternEnd);
						pRec->get_Interval(&lInterval);
						pRec->get_Instance(&lInstance);								
						
						UINT dtStartGroup = (UINT)dtStart;
						SystemTimeToVariantTime(&stToday,&dtNow);
					
					if(fNoEndDate || dtPatternEnd>dtNow)
					{
						switch (lRecurrenceType) 
						{ 
							case olRecursYearly:
									//year should be current year
								GetLocalTime(&stNow);
									//VariantTimeToSystemTime(dtStart, &st);
								VariantTimeToSystemTime(dtPatternStart, &st);
								st.wYear=stNow.wYear;
								SystemTimeToVariantTime(&st,&dtStart);
								SystemTimeToVariantTime(&stToday,&dtNow);
								dtStartGroup = (UINT)dtStart;
								//4/13/10 nYears = ((int)(dtNow - dtPatternStart)) / 365.25;
								nYears = (int)((dtNow - dtPatternStart) / 365.25);
								
								if (nYears > 0 && bIsAllDay)
								{
									//add to description the no of years it's been recurring
									wsprintf(szRecurs, TEXT("(%i)"), nYears+1);	
									StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, szRecurs);
								}
								
								double diff;
								diff = difftime((time_t)dtStart, (time_t)dtNow); //4/13/10 difftime(dtStart, dtNow);

								if (diff>-1) //if date is today or later, add the appointment:
								{
									//if (diff<nTimeSpan+1)//4/8/10
									if(dtStart<dtNow+nTimeSpan)
									{
										data.iGroup=dtStartGroup;
										vApptmnt.push_back(new DataItem(data));
										//delete(&data); //4/5/10 ???
									}
								}	
								else
								{
									StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, szRecurs);
									st.wYear=st.wYear+1;
									SystemTimeToVariantTime(&st,&dtStart);
									if(dtStart<dtNow+nTimeSpan)
									{
										dtStartGroup = (UINT)dtStart;
										data.iGroup=dtStartGroup;
										vApptmnt.push_back(new DataItem(data));
										//delete(&data); //4/5/10 ???
									}
								}
								break;

								default:  //not yearly
									//otherwise only up to the timespan
									//migh be easier to go through the dates from today and 
									//for one month and then use getoccurence to test for occurence
									//for that date
									
									INT dtStartGroup = (UINT)dtStart;
									data.iGroup=dtStartGroup;
									DATE dtDay=dtNow; //4/4/10

									//for (int d= 0; d<31; d++)
									for (int d= 0; d<nTimeSpan; d++)//4/8/10
									{
										dtDay++; //dtNow=dtNow+d;
										pRec->GetOccurrence(dtDay, &prApp); //dtNow, &prApp);
																				
										if(prApp)
										{
											dtStartGroup =  (UINT)dtDay; //dtNow;
											data.iGroup=dtStartGroup;
												//if (dtNow<=dtPatternEnd||fNoEndDate) 
											if (dtDay<=dtPatternEnd||fNoEndDate) 
											{ 
												if(dtDay<dtNow+nTimeSpan)									
													vApptmnt.push_back(new DataItem(data));
												//delete(&data); //4/5/10 ???
											}
										}
									}
								break;

							}//switch (lRecurrenceType) 
								//}//if olRecursDaily
						
						}//if(fNoEndDate || dtPatternEnd>dtNow)					
						}//all appointments
						pRec->Release();

					}	//ifSucceeed
				}//ifRecurring

				else //not recurring
				{
							// grouping: get serial from date
					UINT dtStartGroup = (UINT)dtStart;
					double diff;
					double diff2;
					SystemTimeToVariantTime(&stToday,&dtNow);//4/1
					diff = difftime((time_t)dtStart, (time_t)dtNow);//4/13/10 difftime(dtStart, dtNow);

					//if start date is today or later, add the appointment:
					//if(dtStart==dtNow)
					if (diff>-1) //TEST for allday
					//if (diff>0)//no change
					{
						if(hgScreen.hgScreen == 0) 
						{
							if (diff<nTimeSpan+1)//4/8/10
							//if(dtStart<dtNow+nTimeSpan)
							{
								//MessageBox(0, data.szPrimaryText, L"if (diff>-1)", 0);
								data.iGroup=dtStartGroup;							
								vApptmnt.push_back(new DataItem(data));
								//delete(&data); //4/5/10 ???	
							}
						}
						else //agenda
						{
							if (diff<1)//shows ok							
							{
								data.iGroup = 10;
								vApptmnt.push_back(new DataItem(data));
								//delete(&data); //4/5/10 ???								
							}
						}
					}
					else //start before today
					{
						//MessageBox(0, data.szPrimaryText, L"starts before today", 0);
						hr = pAppointment->get_End(&dtStart);
						CHR(hr);
						diff2 = difftime((time_t)dtNow, (time_t)dtStart);//4/13/10 difftime(dtNow, dtStart);//compare end date to now
						UINT dtStartGroup = (UINT)dtStart;
						//if(diff2<1)
						if(diff2<0)
						{
							if(hgScreen.hgScreen == 2) //agenda
							{
								data.iGroup = 10;
								vApptmnt.push_back(new DataItem(data));
								//delete(&data); //4/5/10 ???								
							}
							else //all appointments
							{
								dtStartGroup = (UINT)dtNow;
								data.iGroup=dtStartGroup;
								vApptmnt.push_back(new DataItem(data));
									//delete(&data); //4/5/10 ???
								
									//dtNow=dtNow++;
								DATE dtDay=dtNow;
								diff2 = difftime((time_t)dtStart, (time_t)dtDay);//4/13/10difftime(dtStart, dtDay);
									//while(diff2<1)
									//if(dtStart<dtNow+nTimeSpan)
									//for (int i= 0; i<nTimeSpan; i++)//4/8/10
									//for (int i=0;i<diff2;i++)
									//if(dtDay<dtNow+nTimeSpan)
								for (int i=0;i<min(nTimeSpan-1,diff2);i++)
								{
									dtDay++;
									dtStartGroup = (UINT)dtDay;//dtStart;
										//dtStartGroup = (UINT)dtNow;
									data.iGroup=dtStartGroup;
									vApptmnt.push_back(new DataItem(data));
									//delete(&data); //4/5/10 ???
								}									
								//}
							}
						}
						//else						
					}
				}// end of not recurring
						//SysFreeString(bstrPrimary);
					
				} 
					//hr=pAppointment->Release();
					//CHR(hr);
				RELEASE_OBJ(pAppointment);//4/8/10				
					//TCHAR szRecurs[255];

				std::sort( vApptmnt.begin(), vApptmnt.end(),compareVect );
				for (unsigned int j=0; j<vApptmnt.size(); j++)
				{					
					adder(vApptmnt.at(j));
					//DataItem *di = vApptmnt.at(j);
						//wsprintf(szRecurs, TEXT("(%i)"), vApptmnt.size());	
						//if(	hgScreen.hgScreen == 0)			
						//MessageBox(0, szRecurs, L"count", 0);
				 }
			}		
		
	//=============TASKS===========================
	if(hgScreen.hgScreen == 1 || hgScreen.hgScreen == 2)  //tasks
	{
		ITask * pTask = NULL;
		DATE dtNow;
		SYSTEMTIME stNow;
		VARIANT_BOOL vbisComplete;
		bool bSortAsc=true;
		TCHAR szSortFilter[32];

		GetLocalTime(&stNow);
		SystemTimeToVariantTime(&stToday,&dtNow);		
		
		hr = polApp->GetDefaultFolder(olFolderTasks, &pCurrFldr); 
		CHR(hr);
		hr = pCurrFldr->QueryInterface(IID_IItem, (LPVOID*)&pItem);
		CHR(hr);

		// Set the folder's properties.
		propval.propid    = PIMPR_FOLDERNOTIFICATIONS;
		propval.val.ulVal = PIMFOLDERNOTIFICATION_ALL;
		hr                = pItem->SetProps(0, 1, &propval);
		CHR(hr);

		hr=pCurrFldr->get_Items(&pItemCol);
		CHR(hr);
			//hr=pItemCol->get_Count(&cItems);
		//sort  4/8/10
		if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Due Date"), -1) == CSTR_EQUAL)
		{
				StringCchCopy(szSortFilter, 32, TEXT("[DueDate]"));
				//hr = pItemCol->Sort(TEXT("[DueDate]"), true); //ajige 5/20
				if (hgScreen.hgScreen == 1)
					bSortAsc=false;	//ajige 5/27
		}
		else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Alphabetical"), -1) == CSTR_EQUAL)
		{
			StringCchCopy(szSortFilter, 32, TEXT("[Subject]"));
				//hr = pItemCol->Sort(TEXT("[Subject]"), true); //ajige 5/20
			bSortAsc=false;
		}
		else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Priority"), -1) == CSTR_EQUAL)
		{
			StringCchCopy(szSortFilter, 32, TEXT("[Importance]"));
				//hr = pItemCol->Sort(TEXT("[Importance]"), false); //ajige 5/20
			//else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Don't Sort"), -1) == CSTR_EQUAL)
			bSortAsc=false;	
		}
		hr = pItemCol->Sort(szSortFilter, bSortAsc);  //ajige 5/21  
		CHR(hr);

		//if(hgScreen.hgScreen == 1)
			//hr=pItemCol->Sort(TEXT("[DueDate]"), false);
		//else
			//hr=pItemCol->Sort(TEXT("[DueDate]"), true);
				//pItemCol->put_IncludeRecurrences(VARIANT_TRUE);
				//pItemCol->Restrict(TEXT("[DueDate] <= \"12/31/2010 08:00 AM\" AND [DateCompleted] < \"2/15/2010 08:00 PM\""),&pItemCol);
				//3/29 hr=pItemCol->Restrict(TEXT("[Complete] = false"), &pItemCol);
				//hr=pItemCol->Restrict(TEXT("[DateCompleted] >=dtNow"), &pItemCol); //doesn't work
				// if(hgScreen.hgScreen == 2)
				//	hr=pItemCol->Restrict(TEXT("[DueDate] <=dtNow"), &pItemCol);
		 
		 hr=pItemCol->get_Count(&cItems);
		 CHR(hr);
		 data.isTask = true;
			
		for(int i=1;i<=cItems;i++)
		{
			DATE dtCompl;
			hr=pItemCol->Item(i,(IDispatch**)&pTask);
			if (FAILED(hr))
				continue;
			// grab properties
			hr = pTask->get_DateCompleted(&dtCompl);			
			CHR(hr);
			hr= pTask->get_Complete(&vbisComplete);//ajige: used for tasks NULL != TODO change
			CHR(hr);
			
			if (vbisComplete && dtCompl<dtNow-1)
				continue;

			hr=pTask->get_Subject(&bstrPrimary);			
			CHR(hr);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, bstrPrimary);
			SysFreeString(bstrPrimary);
			data.ID=i;
			data.isComplete=vbisComplete;
			hr = pTask->get_Oid(&data.oId);
			CHR(hr);
			hr = pTask->get_DueDate(&dtDue);
			CHR(hr);
			// get the date "serial" ??
			//SystemTimeToVariantTime(&stToday, &dtToday);
			//iToday = (UINT)dtToday;
			hr = pTask->get_StartDate(&dtStart);//4/7/10
			CHR(hr);

			if (dtDue < iToday)
				data.isOverdue = true;
			else
				data.isOverdue = false; 
				// grouping: get serial from date
			UINT dtDueGroup = (UINT)dtDue;

			if (NULL == tszCategory) //ajige 4/27 moved
				data.iGroup = dtDueGroup;
		
			// this is the date to be checked for undated tasks!
			SYSTEMTIME stDate;
			VariantTimeToSystemTime(dtDue, &stDate);

			// now check if it is an undated task
			if(stDate.wYear == 4501) // undated task?
			{
				data.isUndated = true;
			}
			else
				data.isUndated = false;

			// due date for overdue tasks, undated string for undated tasks
			if (data.isUndated)
			{
				StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, TEXT(""));			
			}
			else 			{
				_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtDue);
			}
			
//4/8/10
			if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Priority"), -1) == CSTR_EQUAL)
		{
				LONG iImportance = 0;
				pTask->get_Importance(&iImportance);
				data.iGroup=(UINT) iImportance;
				data.iGroup++; //ajige 5/21 doesn't work if 0
		}	//ajige 5/21
		else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Alphabetical"), -1) == CSTR_EQUAL)
		{
				//char c ='';
				//TCHAR buf[2];
				//char c=data.szPrimaryText[0];
				//wsprintf (buf,L"%d", c); 
				//data.iGroup=c; //ajige 5/21 doesn't work if 0
				if(hgScreen.hgScreen != 2) //ajige 6/1 not grouping on tasks for agenda - only sorting
					data.iGroup = (int)_totupper(data.szPrimaryText[0]);
				else
					data.iGroup = 11;
		}	
		else  //sort and group by due date
		{
			UINT dtDueGroup = (UINT)dtDue;
			if(hgScreen.hgScreen == 1)
			{
				//Don't display groups if filtered by category
				if (NULL == tszCategory) //ajige 4/27 moved
					data.iGroup = dtDueGroup;
				
				if(data.isUndated)
						data.iGroup = 1;
				else if(data.isOverdue)
						data.iGroup = 2; // todo: check if this must remain hardcoded				
			}
			else
			{
				//Don't display groups if filtered by category
				if (NULL == tszCategory) 
					data.iGroup = 11;
			}		
			if(data.isOverdue==false)
					StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, TEXT(""));
		}		
		

		if(hgScreen.hgScreen == 2)//agenda
		{
			data.iGroup = 11;
			SYSTEMTIME stNow;
			DATE dtNow;
			GetLocalTime(&stNow);
			//_printDate(data.szTertiaryText, MAX_PATH, dtDue);
			if(data.isOverdue==false)
					StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, TEXT(""));
			SystemTimeToVariantTime(&stToday,&dtNow);
			int diff = (int)difftime((time_t)dtDue, (time_t)dtNow);//4/13/10 difftime(dtDue, dtNow);
			if (diff<1)
				adder(&data);
			else if(dtStart<dtNow)//4/7/10 fo rstartdate before today, but not due yet
				adder(&data);
		}
		else
			adder(&data);

		RELEASE_OBJ(pTask);
		//pTask->Release();
		}
	}
	
	}
#else
	////////////////appointments///////////////////////////////////////////////////
	if(hgScreen.hgScreen == 0 || hgScreen.hgScreen == 2) {

		hr = polApp->GetDefaultFolder(olFolderCalendar, &pCurrFldr); 
		CHR(hr);

		hr = pCurrFldr->QueryInterface(IID_IItem, (LPVOID*)&pItem);
		CHR(hr);

		// Set the folder's properties.
		propval.propid    = PIMPR_FOLDERNOTIFICATIONS;
		propval.val.ulVal = PIMFOLDERNOTIFICATION_ALL;
		hr                = pItem->SetProps(0, 1, &propval);
		CHR(hr);

		// Get the appointments Items collection.
		hr = pCurrFldr->get_Items(&pItemCol);
		CHR(hr);

		// time span filter
		if (hgScreen.hgScreen == 2) // Agenda view, show today only
		{
			nTimeSpan = 1;  
		}
		else // All appointments tab, get time span from settings
		{
			//if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("3 days"), -1) == CSTR_EQUAL)
			//	nTimeSpan = 3;
			//else 
			if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("1 Week"), -1) == CSTR_EQUAL)
				nTimeSpan = 7;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("2 Weeks"), -1) == CSTR_EQUAL)
				nTimeSpan = 14;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("1 Month"), -1) == CSTR_EQUAL)
				nTimeSpan = 31;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("3 Months"), -1) == CSTR_EQUAL)
				nTimeSpan = 92;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("6 Months"), -1) == CSTR_EQUAL)
				nTimeSpan = 183;
			else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->period_filter, -1, TEXT("1 Year"), -1) == CSTR_EQUAL)
				nTimeSpan = 365;
		}

		// write the date to the TCHARs
		wsprintf(szFrom, TEXT("%f\0"), iToday); 
		wsprintf(szTo, TEXT("%f\0"), iToday + nTimeSpan);

		// build the appointments filter string
		StringCchCopy(szDateFilter, MAX_PATH, TEXT("[Start] >= \"<"));
		StringCchCat(szDateFilter, MAX_PATH, szFrom);
		StringCchCat(szDateFilter, MAX_PATH, TEXT("\" AND [Start] < \"<"));  //<=?
		StringCchCat(szDateFilter, MAX_PATH, szTo);
		StringCchCat(szDateFilter, MAX_PATH, TEXT("\""));

		// apply the filter
		hr = pItemCol->Restrict((BSTR)szDateFilter, &pItemCol);
		CHR(hr);

		// include the recurring events
		hr = pItemCol->put_IncludeRecurrences(VARIANT_TRUE);
		CHR(hr);

		IAppointment * pAppointment = NULL;

		int cItems;
		pItemCol->get_Count(&cItems);

		// note: hardcoded to 100, to be changed back
		for (int i = 0; i < 100; i++) {

			// the itemCollection is indexed 1-based, weird...
			hr = pItemCol->Item(i+1, (IDispatch**)&pAppointment);
			if (FAILED(hr))
				continue;

			// grab properties
			hr = pAppointment->get_Oid(&data.oId);
			CHR(hr);

			hr = pAppointment->get_Subject(&bstrPrimary);
			CHR(hr);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, bstrPrimary);
			SysFreeString(bstrPrimary);

			hr = pAppointment->get_Start(&dtStart);
			CHR(hr);

			// grouping: get serial from date
			UINT dtStartGroup = (UINT)dtStart;

			VARIANT_BOOL bIsAllDay = false;
			hr = pAppointment->get_AllDayEvent(&bIsAllDay);
			CHR(hr);

			//ajige 4/16 only do the group code for all appointments screen.
			if(hgScreen.hgScreen == 0) //ajige: not grouping on agenda screen
			{
				if (NULL == tszCategory) {
					data.iGroup = (UINT)dtStartGroup;
				}
			}
			// allelimo: group header for agenda tab
			else
			{
				if (NULL == tszCategory) {
					data.iGroup = 10;
				}
			}


			// show the time or "all day" on the right side
			if(bIsAllDay)
			{
				StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, pSettings->allday_string);
			}
			else
			{
				_printHour(data.szTertiaryText, MAX_PATH, dtStart);
			}

			adder(&data); 

			// clean up
		}

		RELEASE_OBJ(pAppointment);
		pCurrFldr->Release();

	}
	/////////////////////////////end apptmts///////////////////////////////////////

	/////////////////////////////tasks/////////////////////////////////////////////

	if(hgScreen.hgScreen == 1|| hgScreen.hgScreen == 2) {
		hr = polApp->GetDefaultFolder(olFolderTasks, &pCurrFldr);  
		CHR(hr);

		hr = pCurrFldr->QueryInterface(IID_IItem, (LPVOID*)&pItem);
		CHR(hr);

		// Set the folder's properties.
		propval.propid    = PIMPR_FOLDERNOTIFICATIONS;
		propval.val.ulVal = PIMFOLDERNOTIFICATION_ALL;
		hr                = pItem->SetProps(0, 1, &propval);
		CHR(hr);

		// Get the tasks Items collection.
		hr = pCurrFldr->get_Items(&pItemCol);
		CHR(hr);

		// filters:
		// 1 - only not completed tasks
		//if (hgScreen.hgScreen == 1) //ajige 2/11/10 , only on all tasks screen
		{
		hr = pItemCol->Restrict(TEXT("[Complete] = false"), &pItemCol);
		//ajige todo: for items completed today, include on Agenda with strikethrough font
		CHR(hr);
		}

		//ajige 5/21 moved sorting
		bool bSortAsc=true;
		TCHAR szSortFilter[32];
		if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Due Date"), -1) == CSTR_EQUAL)
		{
				StringCchCopy(szSortFilter, 32, TEXT("[DueDate]"));
				//hr = pItemCol->Sort(TEXT("[DueDate]"), true); //ajige 5/20
				if (hgScreen.hgScreen == 2)
					bSortAsc=false;	//ajige 5/27
		}
		else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Alphabetical"), -1) == CSTR_EQUAL)
				StringCchCopy(szSortFilter, 32, TEXT("[Subject]"));
				//hr = pItemCol->Sort(TEXT("[Subject]"), true); //ajige 5/20
		else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Priority"), -1) == CSTR_EQUAL)
		{
			StringCchCopy(szSortFilter, 32, TEXT("[Importance]"));
				//hr = pItemCol->Sort(TEXT("[Importance]"), false); //ajige 5/20
			//else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Don't Sort"), -1) == CSTR_EQUAL)
			bSortAsc=false;	
		}

		if (hgScreen.hgScreen == 2)// && szSortFilter==L"[DueDate]")  //Agenda view, only todays
		{
			// sorting: set to false for ascending order
			//hr = pItemCol->Sort(TEXT("[DueDate]"), VARIANT_FALSE);  //4/17
		//	if(szSortFilter==L"[DueDate]")
		//			bSortAsc=false;	

			hr = pItemCol->Sort(szSortFilter, bSortAsc);  //ajige 5/21  
			CHR(hr);

			// write the date to the TCHARs
			//wsprintf(szFrom, TEXT("%f\0"), iToday); 
			wsprintf(szTo, TEXT("%f\0"), iToday);//dtToday + 1); 

			// build the tasks filter string
			StringCchCopy(szDateFilter, MAX_PATH, TEXT("[DueDate] <= \"<"));
			StringCchCat(szDateFilter, MAX_PATH, szTo);
			StringCchCat(szDateFilter, MAX_PATH, TEXT("\" OR [StartDate] <= \"<"));
			StringCchCat(szDateFilter, MAX_PATH, szTo);
			//and not complete or complete date today
			StringCchCat(szDateFilter, MAX_PATH, TEXT("\""));

			// apply the filter
			hr = pItemCol->Restrict((BSTR)szDateFilter, &pItemCol);
			CHR(hr);

		}
		else //all tasks  
		{
			// sorting code
			// after some testing:
			// removed "categories" according to msdn it is not possible to sort by categories
			// "due date" works
			// "Priority" works (the property name is "importance", changed)
			//		but the grouping looks weird
			// "don't sort" moved to skip
			// maybe we can add "start date"
		//	TCHAR szSortFilter[32];
		//ajige 5/21 moved above to work on agenda screen
		//	if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Due Date"), -1) == CSTR_EQUAL)
				//StringCchCopy(szSortFilter, 32, TEXT("[DueDate]"));
		//		hr = pItemCol->Sort(TEXT("[DueDate]"), true); //ajige 5/20
		//	else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Priority"), -1) == CSTR_EQUAL)
				//StringCchCopy(szSortFilter, 32, TEXT("[Importance]"));
		//		hr = pItemCol->Sort(TEXT("[Importance]"), false); //ajige 5/20
			//else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Don't Sort"), -1) == CSTR_EQUAL)
		//	else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Alphabetical"), -1) == CSTR_EQUAL)
				//StringCchCopy(szSortFilter, 32, TEXT("[]"));
			//	hr = pItemCol->Sort(TEXT("[Subject]"), true); //ajige 5/20
		//
			//hr = pItemCol->Sort(TEXT("[DueDate]"), true);  //4/117
			//hr = pItemCol->Sort(TEXT("[Importance]"), true);			
			hr = pItemCol->Sort(szSortFilter, bSortAsc); //ajige 5/21 VARIANT_TRUE);
			CHR(hr);
		}
		
		ITask * pTask = NULL;

		int cItems;  
		pItemCol->get_Count(&cItems);

		//ajige 4/17
		//for (int i = 0; i < cItems; i++) {
		//didn't make much diff 
		for(int i=cItems;i--;) {

			// the itemCollection is indexed 1-based, weird...
			hr = pItemCol->Item(i+1, (IDispatch**)&pTask);
			if (FAILED(hr))
				continue;

			// grab properties
			hr = pTask->get_Oid(&data.oId);
			CHR(hr);

			hr = pTask->get_Subject(&bstrPrimary); 
			CHR(hr);

			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, bstrPrimary);
			SysFreeString(bstrPrimary);

			data.isTask = true;//ajige: used for tasks NULL != TODO change

			//     _tcsstr(bstrCategories, pSettings->favorite_category);
			// SysFreeString(bstrCategories);
			// Determine if this is a favorite 
			// ajige hr  = pTask->get_Categories(&bstrCategories); 
			// CHR(hr);

			//     _tcsstr(bstrCategories, pSettings->favorite_category);
			// SysFreeString(bstrCategories);
			//ajige 4/16 only grouping on all tasks screen
			//UINT myInt;
			//			UINT uToday = _getDaySerial(&stToday);


			hr = pTask->get_DueDate(&dtDue);
			CHR(hr);

			// get the date "serial"
			SystemTimeToVariantTime(&stToday, &dtToday);
			iToday = (UINT)dtToday;

			// this is the date to be checked for undated tasks!
			SYSTEMTIME stDate;
			VariantTimeToSystemTime(dtDue, &stDate);

			// now check if it is an undated task
			if(stDate.wYear == 4501) // undated task?
			{
				data.isUndated = true;
			}
			else
				data.isUndated = false;

			// check if it is overdue
			if (dtDue < iToday)
				data.isOverdue = true;
			else
				data.isOverdue = false; //ajige: otherwise all but undated is considered overdue

		if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Priority"), -1) == CSTR_EQUAL)
		{
				LONG iImportance = 0;
				pTask->get_Importance(&iImportance);
				data.iGroup=(UINT) iImportance;
				data.iGroup++; //ajige 5/21 doesn't work if 0
		}	//ajige 5/21
		else if(CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Alphabetical"), -1) == CSTR_EQUAL)
		{
				//char c ='';
				//TCHAR buf[2];
				//char c=data.szPrimaryText[0];
				//wsprintf (buf,L"%d", c); 
				//data.iGroup=c; //ajige 5/21 doesn't work if 0
				if(hgScreen.hgScreen != 2) //ajige 6/1 not grouping on tasks for agenda - only sorting
					data.iGroup = (int)_totupper(data.szPrimaryText[0]);
				else
					data.iGroup = 11;
		}	
		else  //sort and group by due date
		{
			// grouping: get serial from date
			UINT dtDueGroup = (UINT)dtDue;

			//now we know if it's overdue, grouping
			if(hgScreen.hgScreen == 1)
			{				 
				//Don't display groups if filtered by category
				if (NULL == tszCategory) //ajige 4/27 moved
					data.iGroup = dtDueGroup;

				if(data.isUndated)
					data.iGroup = 1;

				else if(data.isOverdue)
					data.iGroup = 2; // todo: check if this must remain hardcoded
			}
			// allelimo: group header for agenda tab
			else
			{				 
				//Don't display groups if filtered by category
				if (NULL == tszCategory) 
					data.iGroup = 11;
			}


			// due date for overdue tasks, undated string for undated tasks
			if (data.isOverdue)
			{
				_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtDue);
			}
			else
			{
				StringCchCopy(data.szTertiaryText, SECONDARY_TEXT_LENGTH, TEXT(""));
			}
}
			adder(&data); 

			// clean up
			RELEASE_OBJ(pTask);
			pCurrFldr->Release();
		}
	}
#endif
#endif
	/////////////////////////////end tasks/////////////////////////////////////////

	pCurrFldr->Release();
	hr = S_OK;
	//
Error: 
	RELEASE_OBJ(pItem);//ajige moved  ]from initpoom
		//RELEASE_OBJ(pFolder);//ajige moved, but replaced w/ pFolder. Does pCurrFolder need to be released?
	SysFreeString(bstrPrimary);
		//SysFreeString(bstrCategories);
		//RELEASE_OBJ(pAppointment); //ajige doesn't work anymore??
		//RELEASE_OBJ(pTask); //ajige doesn't work anymore??
	return hr;
}

HRESULT PoomClick(ScreenDefinition  hgScreen,DataItem * data, float x,  
                  int * newScreen, CSettings * pSettings) {
	//ajige hgScreen not necessary
	*newScreen =4;
    return S_OK;
}

HRESULT PoomGetTitle(ScreenDefinition  hgScreen,DataItem * parent, TCHAR * buffer, int cchDest,
                               CSettings * pSettings) {
	//ajige hgScreen not necessary
    StringCchCopy(buffer, cchDest, parent->szPrimaryText);
	
    return S_OK;
}

HRESULT PoomGetGroup(ScreenDefinition  hgScreen, DataItem * data, TCHAR * buffer, int cchDest,
					  CSettings * pSettings) {
	
	UINT g = data->iGroup;
	UINT uToday = _SystemToPoomInt();
	TCHAR strImportance[PRIMARY_TEXT_LENGTH] = {NULL};  //ajige 5/20  
	const TCHAR * day[8] = //4/12/10
				{
					pSettings->sunday_string, pSettings->monday_string, pSettings->tuesday_string,
					pSettings->wednesday_string, pSettings->thursday_string, 
					pSettings->friday_string, pSettings->saturday_string, pSettings->sunday_string 
				}; 
//if edit screen is treated as a list, the grouping would be the title
/*if(hgScreen.hgScreen==4)//4/15/10 details screen, grouping per title
        {
                switch (data->iGroup)
                {                               
                                case 1:
                                        StringCchCopy(buffer, cchDest, pSettings->subject_string);
                                        break;
                                case 2:
                                        StringCchCopy(buffer, cchDest, pSettings->location_string);
                                        break;
                                case 3:
                                        StringCchCopy(buffer, cchDest, pSettings->priority_string);
                                        break;
                                case 4:
                                        StringCchCopy(buffer, cchDest, pSettings->allday_string);
                                        break;
                                case 5:
                                        StringCchCopy(buffer, cchDest, pSettings->duedate_string);
                                        break;
                                case 6:
                                        StringCchCopy(buffer, cchDest, pSettings->starts_string);
                                        break;
                                case 7:
                                                StringCchCopy(buffer, cchDest, pSettings->ends_string);
                                        break;
                                case 8:
                                        StringCchCopy(buffer, cchDest, pSettings->categories_string);
                                        break;
                                case 9:
                                        StringCchCopy(buffer, cchDest, pSettings->status_string);
                                        break;
                                case 10:
                                        StringCchCopy(buffer, cchDest, pSettings->occurs_string);
                                        break;
                                case 11:
                                        StringCchCopy(buffer, cchDest, pSettings->remindme_string);
                                        break;
                                case 12:
                                        StringCchCopy(buffer, cchDest, pSettings->attendees_string);
                                        break;
                                case 13:
                                        StringCchCopy(buffer, cchDest, pSettings->sensitivity_string);
                                        break;
                                case 14:
                                        StringCchCopy(buffer, cchDest, pSettings->notes_string);
                                        break;
                }

        }
        else 
*/
//end if edit screen is list
	//ajige 5/20: only do different grouping on all tasks screen
	if(data->isTask &&
	   CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Priority"), -1) == CSTR_EQUAL)
	{
			switch (data->iGroup)
			{				
				case 2:
					StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  
					StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));
					StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->normal_string);
					break;
				case 3:
					StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  
					StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));
					StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->high_string);
					break;
				case 1:
					StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  
					StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));
					StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->low_string);
					break;
				
			}
		StringCchCopy(buffer, cchDest, strImportance);
		
	}
	else if(data->isTask &&
	   CompareString(LOCALE_NEUTRAL, NORM_IGNORECASE, pSettings->sort_tasks, -1, TEXT("Alphabetical"), -1) == CSTR_EQUAL)
	{
		if(data->iGroup == 11) 
			StringCchCopy(buffer, cchDest, pSettings->alltasks_string);
		else
		{
			buffer[0] = (TCHAR)data->iGroup;
			buffer[1] = 0;
		}
	
	}
	else //group by duedate
	{
		if(data->isUndated) {
			StringCchCopy(buffer, cchDest, pSettings->undated_string);
		}
		// allelimo: group header for agenda tab
		// maybe add fullname of the day of the week?
		else if(data->iGroup == 10) {
			StringCchCopy(buffer, cchDest, pSettings->allappointments_string); 
			//StringCchCopy(data.szPrimaryText, 64, pSettings->allappointments_string);
		} //tried setting cchDest to 64 to show the full string, didn't work
		else if(data->iGroup == 11) {
			StringCchCopy(buffer, cchDest, pSettings->alltasks_string); 
		}
		else if (data->isOverdue){
			StringCchCopy(buffer, cchDest, pSettings->overdue_string);
		}
		else if (g - uToday == 0) {  
			StringCchCopy(buffer, cchDest, pSettings->today_string);
		}
		else if (g - uToday == 1) {
			StringCchCopy(buffer, cchDest, pSettings->tomorrow_string);
		}
		else if (g - uToday <= 7) {
			g = g % 7;
			StringCchCopy(buffer, cchDest, 
				g == 0 ? pSettings->saturday_string
				: g == 1 ? pSettings->sunday_string
				: g == 2 ? pSettings->monday_string
				: g == 3 ? pSettings->tuesday_string
				: g == 4 ? pSettings->wednesday_string
				: g == 5 ? pSettings->thursday_string
				: pSettings->friday_string
			);
		}
		else {
				SYSTEMTIME st;
				VariantTimeToSystemTime(g, &st);
								
				GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,NULL, buffer, cchDest);		
				
				//4/12/10
				StringCchCat(buffer, cchDest, L": ");
				StringCchCat(buffer, cchDest, day[st.wDayOfWeek]);		
				
		}
	}

	return S_OK;
}

HRESULT PoomAddItem(ScreenDefinition  hgScreen) {
    IDispatch * pDisp = NULL;
    IItem * pItem = NULL;
    HRESULT hr = S_OK;
    HWND hWnd;

    hr = initPoom(); //hgScreen);//ajige added hgScreen
    CHR(hr);
	if(hgScreen.hgScreen==0)
		hr = polApp->CreateItem(olAppointmentItem, (IDispatch**)&pDisp); 
    else if(hgScreen.hgScreen==1)
		hr = polApp->CreateItem(olTaskItem, (IDispatch**)&pDisp);
    	
	CHR(hr);

    hr = pDisp->QueryInterface(IID_IItem, (LPVOID*)&pItem);
    CHR(hr);

    hWnd = FindWindow (SZ_APP_NAME, NULL);
	hr = pItem->Edit(hWnd);

Error:
	RELEASE_OBJ(pItem);
    RELEASE_OBJ(pDisp);
    return hr;
}

// *************************************************
// These functions are for the favorites list of appointments
// *************************************************


// *************************************************
// These functions are for an appointment details screen
// *************************************************

HRESULT PoomDetailsPopulate(ScreenDefinition hgScreen, DataItem * parent, void (*adder)(DataItem*),
							CSettings * pSettings) {
	//hgscreen=0
	
	HRESULT hr = S_OK;

	IAppointment * pAppointment = NULL; 
	ITask * pTask = NULL;
	IDispatch * pDisp = NULL;
	IItem * pItem = NULL;
	
	BSTR buffer = NULL;

	BSTR bstrCategories = NULL;
		//ajige not used int id = parent->ID;

	TCHAR * szName = parent->szPrimaryText;
		//DWORD dwNumberOfBytesWritten = 0;
	
	//allelimo
	DATE dtBuffer;
	VARIANT_BOOL bIsAllDay;
	VARIANT_BOOL vbisComplete; //14/14/10
	LONG iStatus = 0;
	TCHAR strStatus[PRIMARY_TEXT_LENGTH] = {NULL};
	LONG iImportance = 0;
	TCHAR strImportance[PRIMARY_TEXT_LENGTH] = {NULL};
	int type;
		//reminder
		//VARIANT_BOOL bReminder;
		//LONG iReminderMinutes;

	// Initialize the data item that we're going to write
	DataItem data = {0};
	data.ID = 0;
	data.iGroup = 0;
	data.isTask = false; 
	data.isOverdue = false;
	data.oId = parent->oId;

	hr = initPoom();
	CHR(hr);
	
	hr = polApp->GetItemFromOid(data.oId, (IDispatch**)&pDisp);
	CHR(hr);

	hr = pDisp->QueryInterface((IID_IItem), (LPVOID*)&pItem);
	CHR(hr);
	pItem->get_DefaultItemType(&type);
		//data.type=diLocation;//4/15/10
		//data.type=diSubject; //4/21/10

/////////////////////////////appointments//////////////////////////////////////

	if (type == 1) //ajige apptmt
	{
		data.isTask=false; //4/15/10
		hr = polApp->GetItemFromOid((CEOID)data.oId, (IDispatch**)&pAppointment);
		CHR(hr);

		// Subject 
		pAppointment->get_Subject(&buffer);
		StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
		SysFreeString(buffer);
		data.type = diSubject;
			//data.iGroup=1;
		adder(&data); 

		// Location 
		pAppointment->get_Location(&buffer);
		StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
		SysFreeString(buffer);
		data.type = diLocation;
		//data.iGroup=2;
		adder(&data); 

		// Item status	
		pAppointment->get_BusyStatus(&iStatus);
		switch (iStatus) {
			case olFree:			
				//StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->status_string);  //TEXT("Priority: Low")			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, TEXT(": "));			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, pSettings->free_string);
				StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->free_string); 
				break;		
			case olTentative:			
				//StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->status_string);  //TEXT("Priority: Low")			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, TEXT(": "));			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, pSettings->tentative_string);
				StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->tentative_string); 
				break;
			case olBusy:			
				//StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->status_string);  //TEXT("Priority: Low")			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, TEXT(": "));			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, pSettings->busy_string);		
				StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->busy_string); 
				break;		
			case olOutOfOffice:			
				//StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->status_string);  //TEXT("Priority: Low")			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, TEXT(": "));			
				//StringCchCat(strStatus, PRIMARY_TEXT_LENGTH, pSettings->outofoffice_string);	
				StringCchCopy(strStatus, PRIMARY_TEXT_LENGTH, pSettings->outofoffice_string); 
				break;
				//default:		
				//	StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  //TEXT("Priority: Low")		
				//	StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));		
				//	StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->normal_string);	
		}	

		//StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, strStatus);	
		data.type = diStatus;	
		//data.iGroup=9;
		adder(&data); 

		// Start and End date/time
		pAppointment->get_AllDayEvent(&bIsAllDay);

		if(bIsAllDay) {
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->allday_string);
			//5/2/10
			//startdate
			pAppointment->get_Start(&dtBuffer);
			_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtBuffer);
			StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->starts_string);
			data.type = diDateTime; 
				//data.iGroup=4;
			adder(&data);
			//enddate
			pAppointment->get_End(&dtBuffer); 
			_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtBuffer);
			StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->ends_string);
			//end 5/2/10
			data.type = diDateTime; 
				//data.iGroup=4;
			adder(&data);
		}
		else {
			
			// start
			pAppointment->get_Start(&dtBuffer);
			// start time
			_printHour(data.szPrimaryText, PRIMARY_TEXT_LENGTH, dtBuffer);
			StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->starts_string);
			// start date
			_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtBuffer);
			data.type = diDateTime; 
			//data.iGroup=6;
			adder(&data);

			// end
			pAppointment->get_End(&dtBuffer); 
			// end time
			_printHour(data.szPrimaryText, PRIMARY_TEXT_LENGTH, dtBuffer);
			StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->ends_string);
			// end date
			_printDate(data.szTertiaryText, SECONDARY_TEXT_LENGTH, dtBuffer);
			data.type = diDateTime; 
			//data.iGroup=7;
			adder(&data);
		}

		//recurrence 4/14/10
        //TODO: doesn't work
        hr=pAppointment->get_IsRecurring(&vbisComplete);
        CHR(hr);
        if(vbisComplete)
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"Is recurring");
        else 
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"No recurrence");
			//StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
			//SysFreeString(buffer);
        data.type = diOccurs;
			 //data.type = diStatus;
			//data.iGroup=10;
        adder(&data); 

        //reminder 4/14/10
        hr=pAppointment->get_ReminderSet(&vbisComplete);
        CHR(hr);
        if(vbisComplete)
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"Reminder");
        else 
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"No reminder");
        //StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
        //SysFreeString(buffer);
        data.type = diReminder;
        //data.type = diStatus;
        //data.iGroup=11;
        adder(&data);
		

		// Category
		pAppointment->get_Categories(&buffer);
		StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
		SysFreeString(buffer);
		data.type = diCategory;
		//data.iGroup=8;
		adder(&data); 

		//sensitivity
 hr=pAppointment->get_Sensitivity(&iImportance);
                CHR(hr);
                switch (iImportance)
                {
                        case olNormal://from StringCchCat
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->normal_string);
                                break;
                        case olPersonal:
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->personal_string);
                                break;
                        case olPrivate:
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->private_string);
                                break;
                        case olConfidential:
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->confidential_string);
                                break;
                }       
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, strImportance);
                //SysFreeString(strImportance);
                data.type = diSensitivity;
                //data.iGroup=13;
                adder(&data); 

		//notes 4/14/10
                hr=pAppointment->get_Body(&buffer);
                CHR(hr);
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
                SysFreeString(buffer);
                data.type = diNotes;
                //data.iGroup=14;
                adder(&data);           
		
		//Attendees
				//notes 4/14/10
                //hr=pAppointment->get_Recipients(&buffer); //=> doesn't work
                //CHR(hr);
                //StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
                //SysFreeString(buffer);
                //data.type = diAttendees;
                //data.iGroup=14;
                //adder(&data);       

		
	} 
/////////////////////////////end appointments//////////////////////////////////


////////////////////////////tasks//////////////////////////////////////////////

	else if (type == 3) {
		
		hr = polApp->GetItemFromOid((CEOID)data.oId, (IDispatch**)&pTask);
		CHR(hr);
		data.isTask=true; //4/15/10

		// subject
		hr=pTask->get_Subject(&buffer);
		CHR(hr);
		StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
			//StringCchCopy(EditValuesT[0], MAX_LOADSTRING, buffer);
		SysFreeString(buffer);
		data.type = diSubject;
		adder(&data); 

		//allelimo - importance/priority
		hr=pTask->get_Importance(&iImportance);
		CHR(hr);

		switch (iImportance)
		{
			case olImportanceLow:
					//StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  //TEXT("Priority: Low")
					//StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));
					//StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->low_string);
				StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->low_string);
				break;
			case olImportanceHigh:
					//StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  //TEXT("Priority: Low")
					//StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));
					//StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->high_string);
				StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->high_string);
				break;//ajige 5/20
			default: //case olImportanceNormal:
					//StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->priority_string);  //TEXT("Priority: Low")
					//StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, TEXT(": "));
					//StringCchCat(strImportance, PRIMARY_TEXT_LENGTH, pSettings->normal_string);
				StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->normal_string);	
				break;
		}
			//StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, strImportance);
		data.type = diImportance;
			//data.iGroup=3;
		adder(&data);

		//Status 4/14/10
            hr=pTask->get_Complete(&vbisComplete);
            CHR(hr);
            if(vbisComplete)
                    StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"Complete");
            else 
                    StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"Not Complete");
            //SysFreeString(buffer);
            //vbisComplete=NULL;
            data.type = diStatus; 
            //data.iGroup=9;
            adder(&data); 

            // start date
            if (parent->isUndated)
            {
                    StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->undated_string);
            }
            else 
            {
                    hr=pTask->get_StartDate(&dtBuffer);
                    CHR(hr);
                    _printDate(data.szPrimaryText, PRIMARY_TEXT_LENGTH, dtBuffer);
                    //StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->duedate_string);
            }
            StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->starts_string); //4/15/10

            data.type = diDateTime; 
            //data.iGroup=6;
            adder(&data);


		// due date
		if (parent->isUndated)
		{
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->undated_string);
		}
		else 
		{
			hr=pTask->get_DueDate(&dtBuffer);
			CHR(hr);
			_printDate(data.szPrimaryText, PRIMARY_TEXT_LENGTH, dtBuffer);
			StringCchCopy(data.szSecondaryText, SECONDARY_TEXT_LENGTH, pSettings->duedate_string);
		}
		data.type = diDateTime; 
		//data.iGroup=5;
		adder(&data);

		//recurrence 4/14/10
                //doesn't work
                hr=pTask->get_IsRecurring(&vbisComplete);
                CHR(hr);
                if(vbisComplete)
                        StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"Is recurring");
                else 
                        StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"No recurrence");
                //StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
                //SysFreeString(buffer);
                data.type = diOccurs;
                //data.type = diStatus;
                //data.iGroup=10;
                adder(&data); 

                //reminder 4/14/10
                hr=pTask->get_ReminderSet(&vbisComplete);
                CHR(hr);
                if(vbisComplete)
                        StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"Reminder");
                else 
                        StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, L"No reminder");
                //StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
                //SysFreeString(buffer);
                data.type = diReminder;
                //data.type = diStatus;
                //data.iGroup=11;
                adder(&data);

		// Category
		hr=pTask->get_Categories(&buffer);
		CHR(hr);
		StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
		SysFreeString(buffer);
		data.type = diCategory;
		//data.iGroup=8;
		adder(&data); 
	

	//data.type=diSubject;
                 hr=pTask->get_Sensitivity(&iImportance);
                CHR(hr);
                switch (iImportance)
                {
                        case olNormal://from StringCchCat
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->normal_string);
                                break;
                        case olPersonal:
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->personal_string);
                                break;
                        case olPrivate:
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->private_string);
                                break;
                        case olConfidential:
                                StringCchCopy(strImportance, PRIMARY_TEXT_LENGTH, pSettings->confidential_string);
                                break;
                }       
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, strImportance);
                //SysFreeString(strImportance);
                data.type = diSensitivity;
                //data.iGroup=13;
                adder(&data); 

                //Attendees 4/14/10
                //??????????

                //notes 4/14/10
                hr=pTask->get_Body(&buffer);
                CHR(hr);
                StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, buffer);
                SysFreeString(buffer);
                data.type = diNotes;
                //data.iGroup=14;
                adder(&data);           
        }
	// Reminder
	//pAppointment->get_ReminderSet(&bReminder);
	//pAppointment->get_ReminderMinutesBeforeStart(&iReminderMinutes);
	/*
	pseudo-code
	if(reminder)
	string->"Reminder: 10 minutes"
	*/

////////////////////////////end tasks//////////////////////////////////////////


	//ajige the buttons for manage and edit should be fixed at the bottom of the screen, sharing one line
	//not be part of the list

	// Button to show details  //
	//data.type = diDetailsButton;
		//if(type == 1)
		//	StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->manageappointment_string);
		//else 
	//if(type == 3)
	//{
	//	StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->managetask_string);//=complete
	//	adder(&data); //ajige 5/28 only for tasks to mark complete. To view click subject
	//}
	//SysFreeString(buffer);
	

	// Button to edit appointment & task
	//4/22/10 changed to view
	data.type = diEditButton;
	StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->manageappointment_string); //4/26/10view in outlook
	SysFreeString(buffer);
	adder(&data); 

	hr = S_OK;

Error:
	// cleanup
	if (NULL != bstrCategories)
		SysFreeString(bstrCategories);
	if (NULL != buffer)
		SysFreeString(buffer);
	RELEASE_OBJ(pAppointment); //allelimo
	RELEASE_OBJ(pTask); 
	return hr;
}


HRESULT PoomDetailsGetTitle(ScreenDefinition hgScreen, DataItem * parent, TCHAR * buffer, 
							int cchDest, CSettings * pSettings) {
	//ajige hgScreen not necessary
    StringCchCopy(buffer, cchDest, pSettings->details_string);
	
    return S_OK;
}

HRESULT PoomDetailsClick(ScreenDefinition hgScreen, DataItem * data, float x, 
                         int * newScreen, CSettings * pSettings) {
//ajige hgScreen not necessary   
	HRESULT hr = S_OK;
    IDispatch * pDisp = NULL;
    IItem * pItem = NULL;
	ITask * pTask = NULL;
    HWND hWnd = 0;

    int oid = data->oId;
    if (oid == -1)
        return E_INVALIDARG;

    hr = initPoom();//hgScreen);
    CHR(hr);

    hr = polApp->GetItemFromOid(oid, &pDisp);
    CHR(hr);

    switch (data->type) {
		case diSubject:  //ajige 5/29 so that when clicking subject, will go to view
            hr = pDisp->QueryInterface(IID_IItem, (LPVOID*)&pItem);
            CHR(hr);
            hWnd = FindWindow (SZ_APP_NAME, NULL);
        	hr = pItem->Display(hWnd);
			CHR(hr);
            break;
		
		case diStatus:
			//MessageBox(0,L"Status",L"poomdetailsclick",0);
			//ExpandIt(hWnd, 1);			
			break;

        case diEditButton:
            hr = pDisp->QueryInterface(IID_IItem, (LPVOID*)&pItem);
            CHR(hr);
            hWnd = FindWindow (SZ_APP_NAME, NULL);
        	hr = pItem->Display(hWnd);
			CHR(hr);
            break;

       /* case diDetailsButton:
			hr = pDisp->QueryInterface(IID_IItem, (LPVOID*)&pItem);
			CHR(hr);
			hWnd = FindWindow (SZ_APP_NAME, NULL);
			int type;
			pItem->get_DefaultItemType(&type);
			if(type==3) //ajige task is 3, mark task complete
			{
				int iMsg = MessageBox(NULL, pSettings->edittask_string, TEXT("iAgenda"), MB_YESNO|MB_ICONQUESTION); //TODO: text from settings?
				if (iMsg == IDYES)
				{
					TCHAR findfilter[MAX_PATH] = TEXT("[Oid]="); 
					TCHAR b[20];  
					long  oid;

					hr = polApp->GetDefaultFolder(olFolderTasks, &pCurrFldr);   //ajige
					CHR(hr);
					hr=pCurrFldr->get_Items(&pItemCol);  //ajige
					CHR(hr);					
					hr=pItem->get_Oid(&oid);
					CHR(hr);
					wsprintf(b,  TEXT("%d"), oid); 			
					StringCchCat(findfilter, MAX_PATH, b);
					hr=pItemCol->Find((BSTR)findfilter,(IDispatch **)(&pTask));
					CHR(hr);
					hr=pTask->put_Complete(VARIANT_TRUE);  //or -1
					CHR(hr);
					hr=pTask->Save();
					CHR(hr);
					PostMessage(hWnd, WM_COMMAND, CMD_BACK, EXPAND_DETAILS_PERIOD);//5/14  0); //ajige5/11
				}
				
			}
			else
			{
        		hr = pItem->Display(hWnd);
				CHR(hr);
			}
            break;*/
    }
	
				//if (LastY>=rHeader.top 
				//    && LastY < rHeader.top  +HEADER_CLICK_HEIGHT * vga  //bottom//5/13 ajige from: top  +HEADER_CLICK_HEIGHT * vga
				///	&& Screens[History[depth].screen].parent == 0 
				//	&& pt.y >= rHeader.top //agige 5/19 added to be able to cancel when moving away
				//    && pt.y < rHeader.top + HEADER_CLICK_HEIGHT * vga )
				//{
			   // else if (depth > 0 && pt.y >= rHeader.top 
				//    && pt.y < rHeader.top + HEADER_CLICK_HEIGHT * vga 
				//    && pt.x <= HEADER_CLICK_HEIGHT * vga
				//	&& Screens[History[depth].screen].parent == 0 ) { //ajige 4/23

    hr = S_OK;

Error:
	RELEASE_OBJ(pItem);
	RELEASE_OBJ(pTask);
    RELEASE_OBJ(pDisp);
    return hr;
}


HRESULT EditPopulate(ScreenDefinition hgScreen, DataItem * parent, void (*adder)(DataItem*),
							CSettings * pSettings) {
	//hgscreen=0
	
	HRESULT hr = S_OK;
	DataItem data = {0};
	data.isTask=true; //in order to add checkboxes
	data.type=diListItem;	
				
	switch (parent->type)
	{
		case diImportance:
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->low_string);	
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->normal_string);
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->high_string);		
			adder(&data);
			break;
		case diSensitivity:
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->normal_string);	
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->personal_string);
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->private_string);		
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->confidential_string);		
			adder(&data);
			break;
		case diStatus:
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->free_string);	
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->tentative_string);
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->busy_string);		
			adder(&data);
			StringCchCopy(data.szPrimaryText, PRIMARY_TEXT_LENGTH, pSettings->outofoffice_string);		
			adder(&data);
			break;
	
	}
	
	hr = S_OK;


	return hr;
}


HRESULT EditGetTitle(ScreenDefinition hgScreen, DataItem * parent, TCHAR * buffer, 
							int cchDest, CSettings * pSettings) 
{
	switch (parent->type)
	{
		case diImportance:
			StringCchCopy(buffer, cchDest, pSettings->priority_string);
			break;
		case diSensitivity:
			StringCchCopy(buffer, cchDest, pSettings->sensitivity_string);
			break;
		case diStatus:
			StringCchCopy(buffer, cchDest, pSettings->status_string);
			break;	
	}
	
    return S_OK;
}

HRESULT EditClick(ScreenDefinition hgScreen, DataItem * data, float x, 
                         int * newScreen, CSettings * pSettings) {
*newScreen =5;
    return S_OK;
}

// *************************************************
// Internal functions to be used only by the functions in this file
// *************************************************

HRESULT initPoom(){//not necessaryScreenDefinition  hgScreen) {
	HWND      hWnd     = 0;
    HRESULT   hr       = 0;
   	
    if (polApp == NULL) {
        hr = CoCreateInstance(__uuidof(Application), NULL, CLSCTX_INPROC_SERVER,
                              __uuidof(IPOutlookApp2), (LPVOID*) &polApp);
        CHR(hr);
    
		hWnd = FindWindow (SZ_APP_NAME, NULL);
        hr = polApp->Logon((long)hWnd);
        CHR(hr);
		
		// register for updates
		// http://msdn.microsoft.com/en-us/library/ms862902.aspx
    
	    // Get the folder for appointments.
	
    }

    hr = S_OK;

Error:
		//RELEASE_OBJ(pItem);//ajige moved 
		//RELEASE_OBJ(pFolder);//ajige moved 
    if (FAILED(hr)) {
        // If we failed to log on, don't keep the object around
        RELEASE_OBJ(polApp);
    }
    return hr;
}